﻿/* Rick van Bodegraven - 0915335
 * 0915335bodegraven@hszuyd.nl
 * 
 * Nick Nijenhuis - 0808334
 * 0808334nijenhuis@hszuyd.nl
 * 
 * 11-10-2010 - Versie 0.1
 * 12-10-2010 - Versie 0.2
 * 13-10-2010 - Versie 0.3
 * 14-10-2010 - Versie 0.4
 * 
 * Zie SVN voor veranderingen.
 * 
 * Het model. Bevat alle vakken waarop gespeeld wordt, inclusief spelerlocaties. 
 */

using System.Collections.Generic;
using System.Linq;
using Roborally.Bord;
using Roborally.CommonData.GlobaleTypes;
using System;

namespace Roborally.Server
{
    /// <summary>
    /// Een instantie van Model houdt de gegevens van het spel bij.
    /// </summary>
    public class Model : IModel
    {
        #region Property's & Fields
        private IVak[,] vakken;
        private List<ModelSpelerInfo> modelSpelerInfos = new List<ModelSpelerInfo>();
        public event ModelGewijzigdHandler ModelGewijzigd;
        #endregion

        /// <summary>
        /// De vakken van een bord
        /// </summary>
        public IVak[,] Vakken
        {
            get
            {
                IVak[,] vakkenKloon = new IVak[vakken.GetLength(0), vakken.GetLength(1)];
                vakkenKloon = vakken;
                return vakkenKloon;
            }
        }

        /// <summary>
        /// De ModelSpelerInfos getter
        /// </summary>
        public List<ModelSpelerInfo> ModelSpelerInfos
        {
            get { return modelSpelerInfos; }
        }

        //public Model(IVak[,] vakken, List<ModelSpelerInfo> spelerInfos)
        //{
        //    IVak[,] vakkenKloon = new IVak[vakken.GetLength(0), vakken.GetLength(1)];
        //    Vakken.CopyTo(vakkenKloon, 0);
        //    this.vakken = vakkenKloon;

        //    this.modelSpelerInfos = spelerInfos.ToList();
        //}

        /// <summary>
        /// Constructor voor Model, maak een model van gekozenBord en de modelSpelerInfo
        /// </summary>
        /// <param name="gekozenBord">het gekozen speelbord</param>
        /// <param name="modelSpelerInfo">de informatie van de spelers</param>
        public Model(IBord gekozenBord, List<ModelSpelerInfo> modelSpelerInfo)
        {
            this.vakken = gekozenBord.Vakken;
            this.modelSpelerInfos = modelSpelerInfo;//new List<ModelSpelerInfo>(modelSpelerInfo);
        }

        /// <summary>
        /// Constructor voor Model
        /// </summary>
        public Model()
        {
            // TODO: Complete member initialization
        }

        /// <summary>
        /// Private constructor voor het klonen van het model
        /// </summary>
        /// <param name="vakken">het originele speelbord</param>
        /// <param name="spelersInfo">de info over de spelers</param>
        private Model(IVak[,] vakken, List<ModelSpelerInfo> spelersInfo)
        {
            //Kloon IVak[,]
            IVak[,] vakkenKloon = new IVak[vakken.GetLength(0), vakken.GetLength(1)];
            for (int i = 0; i < vakken.GetLength(0); i++)
                for (int j = 0; j < vakken.GetLength(1); j++)
                    vakkenKloon[i, j] = vakken[i, j];

            //Kloon ModelSpelersInfo List
            List<ModelSpelerInfo> spelersInfoKloon = new List<ModelSpelerInfo>(spelersInfo);

            this.vakken = vakkenKloon;
            this.modelSpelerInfos = spelersInfoKloon;
        }

        /// <summary>
        /// Maak een kopie van het model
        /// </summary>
        /// <returns></returns>
        /// <remarks>Maakt gebruik van de private constructor</remarks>
        public IModel Kloon()
        {
            return (new Model(vakken, modelSpelerInfos) as IModel);
        }

        /// <summary>
        /// Event wordt gefired
        /// </summary>
        private void OnModelGewijzigd()
        {
            if (ModelGewijzigd != null)
                ModelGewijzigd(Kloon);
        }

        /// <summary>
        /// ModelSpelerInfos getter
        /// </summary>
        List<ModelSpelerInfo> IModel.ModelSpelerInfos
        {
            get
            {
                return modelSpelerInfos;
            }
            set
            {
                ///???? niet benodigd?
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Controller roept deze methode aan zodra het model is aangepast
        /// </summary>
        public void UpdateModel()
        {
            OnModelGewijzigd();
        }
    }
}